﻿namespace Knownet.Utils
{
  using System;
  using System.Text;

  /// <summary>
  /// 文本中字符的位置。
  /// </summary>
  public class Location
  {
    #region Statics
    public static Location CreateInstance()
    {
      return new Location();
    }
    public static Location of(int row, int rowChar, int col)
    {
      return new Location(row,rowChar,col);
    }
    public static readonly Location Null = CreateInstance();
    #endregion
    #region Fields
    /// <summary>
    /// 字符所在行（从1开始计算）。
    /// </summary>
    protected int row =1;
    /// <summary>
    /// 字符所在列（从0开始计算）。
    /// </summary>
    protected int col =0;
    /// <summary>
    /// 字符所在行中的位置（从0开始计算）。
    /// </summary>
    protected int rowChar =0;
    #endregion
    #region Properties
    /// <summary>
    /// 获取字符所在行。
    /// </summary>
    public virtual int Row
    {
      get
      {
        return this.row;
      }
    }
    /// <summary>
    /// 获取字符所在行中的位置。
    /// </summary>
    public virtual int RowChar
    {
      get
      {
        return this.rowChar;
      }
    }
    /// <summary>
    /// 获取字符所在列。
    /// </summary>
    public virtual int Column
    {
      get
      {
        return this.col;
      }
    }
    /// <summary>
    /// 判断当前位置是否为Location.Null。
    /// </summary>
    public virtual bool IsNull
    {
      get
      {
        return object.ReferenceEquals(this, Null);
      }
    }
    #endregion
    #region Constructors
    public Location ()
    {

    }
    public Location(Location l)
    {
      if (l != null)
      {
        this.row = l.row;
        this.col = l.col;
        this.rowChar = l.rowChar;
      }
    }
    public Location(int row, int rowChar, int col)
    {
      this.row = row;
      this.col = col;
      this.rowChar = rowChar;
    }
    #endregion
    #region Methods
    /// <summary>
    /// 复制当前位置记录。
    /// </summary>
    /// <returns>当前位置记录的复本。</returns>
    /// <remarks>
    /// 由于Location是引用类型，
    /// 当记录Location的时候，请记录
    /// 它的复制品。
    /// </remarks>
    public virtual Location Duplicate()
    {
      return new Location(this);
    }
    /// <summary>
    /// 增加一行。
    /// </summary>
    /// <returns>增加后的位置。</returns>
    public virtual Location IncreaseRow()
    {
      //row     从 1 开始计数，每一行增加 1。
      this.row++;
      //column  从 0 开始计数，每个行尾置 0。
      this.col = 0; 
      //rowChar 从 0 开始计数，每个行尾置 0。
      this.rowChar = 0;
      return this;
    }
    /// <summary>
    /// 在当前行上增加字符。
    /// </summary>
    /// <param name="tabCount">tab对应的字符数量。</param>
    /// <returns>增加后的位置。</returns>
    public virtual Location IncreaseChar(int tabCount)
    {
      this.rowChar++;
      this.col += (tabCount>1)?tabCount:1;
      return this;
    }
    /// <summary>
    /// 生成位置的字符串表述。
    /// </summary>
    public override string ToString()
    {
      return string.Format("Row {0},Col {1}, At {2}", this.Row, this.Column,this.RowChar);
    }
    #endregion
  }
}
